<template>
    <div id="hxm-picker">
        <transition name="hxmui-fade">
            <div v-show="visible" @click="cancel" class="overlay">
                <transition name="hxmui-slide-bottom">
                    <div class="hxm-picker-container" @click.stop v-if="visible">
                        <div class="hxm-picker-head">
                            <div class="hxm-picker-cancel" @click="cancel">
                                <span>{{ cancelText }}</span>
                            </div>
                            <div class="hxm-picker-title">
                                <span>{{ title }}</span>
                            </div>
                            <div class="hxm-picker-submit" @click="confirm">
                                <span>{{ confirmText }}</span>
                            </div>
                        </div>
                        <div class="hxm-picker-panel">
                            <div class="hxm-picker-wheel-wrapper">
                                <div class="hxm-picker-wheel" ref="wheeloptions">
                                    <ul class="hxm-picker-wheel-scroll" :style="{ top: '160px' }">
                                        <li class="hxm-picker-wheel-item" v-for="(item, index) in menu" :key="index">
                                            <span>{{ item }}</span>
                                        </li>
                                    </ul>
                                </div>
                                <div class="hxm-picker-mask-top"></div>
                                <div class="hxm-picker-mask-bottom"></div>
                            </div>
                        </div>
                    </div>
                </transition>
            </div>
        </transition>
    </div>
</template>
<script lang="ts" setup>
import { nextTick, ref, watch } from 'vue';

interface Props {
    visible: boolean;
    cancelText?: string;
    title?: string;
    confirmText?: string;
    menu: string[];
    selectIndex: number;
}
const props = withDefaults(defineProps<Props>(), {
    visible: true,
    cancelText: '取消',
    title: '',
    confirmText: '完成',
    selectIndex: 0,
})
interface Emits {
    (e: 'cancel'): void;
    (e: 'confirm', selectedIndex: number): void;
}
const emits = defineEmits<Emits>();
const wheeloptions = ref<HTMLElement>();
let wheel: any;
const cancel = () => {
    emits('cancel');
}
const confirm = () => {
    emits('confirm', wheel.selectedIndex);
}
const init = () => {
    nextTick(() => {
        if (!wheeloptions.value) {
            return
        }
        wheel = new window.BScroll(wheeloptions.value, {
            wheel: {
                selectedIndex: props.selectIndex >= 0 ? props.selectIndex : 0,
                rotate: 22,
            },
            swipeTime: 2500,
            momentumLimitDistance: 10,
        })
    })
}

// 监听数据变化进而初始化
watch(() => props.menu, (nVal) => {
    if (nVal.length) {
        init();
    }
}, {
    immediate: true
})
watch(() => props.visible, (nVal) => {
    if (nVal) {
        init()
    }
}, {
    immediate: true
})
</script>
<style lang="less" scoped>
@keyframes hxmui-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes hxmui-fade-out {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

@keyframes hxmui-slide-bottom-enter {
    from {
        opacity: 0;
        transform: translate3d(0, 80%, 0);
    }

    to {
        opacity: 1;
    }
}

@keyframes hxmui-slide-bottom-out {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
        transform: translate3d(0, 80%, 0);
    }
}

.hxmui-fade {
    &-enter-active {
        animation: 0.3s hxmui-fade-in both ease-in;
    }

    &-leave-active {
        animation: 0.3s hxmui-fade-out both ease-out;
    }
}

.hxmui-slide-bottom {
    &-enter-active {
        animation: hxmui-slide-bottom-enter .3s both ease-in-out;
    }

    &-leave-active {
        animation: hxmui-slide-bottom-out .3s both ease-in-out;
    }
}

#hxm-picker {
    .overlay {
        display: flex;
        align-items: flex-end;
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        background-color: rgba(0, 0, 0, .6);
        z-index: 1;
    }

    .hxm-picker-mask-top {
        top: 0;
        border-bottom: 1px solid rgba(255, 255, 255, .9);
        background: linear-gradient(to bottom, rgba(255, 255, 255, .9), rgba(255, 255, 255, .5));
    }

    .hxm-picker-mask-bottom {
        bottom: 0;
        border-top: 1px solid rgba(255, 255, 255, .9);
        background: linear-gradient(to top, rgba(255, 255, 255, .9), rgba(255, 255, 255, .5));
    }

    .hxm-picker-container {
        border-radius: 24px 24px 0 0;
        width: 100%;
        background-color: #fff;
    }

    .hxm-picker-head {
        display: flex;
        position: relative;
        line-height: 97px;

        &>div {
            height: 100%;
            align-content: stretch;
            display: flex;
            align-items: center;
        }

        &:after {
            content: '';
            display: block;
            border-bottom: 1px solid #ebebeb;
            left: 0;
            right: 0;
            -webkit-transform: scaleY(.5);
            transform: scaleY(.5);
        }

        .hxm-picker-cancel {
            flex: 1;
            padding-left: 24px;
            font-family: PingFangSC-Regular;
            font-size: 24px;
            color: rgba(0, 0, 0, 0.84);
            text-align: center;
            font-weight: 400;
            justify-content: flex-start;

            span {
                font-size: 32px;
            }
        }

        .hxm-picker-submit {
            font-family: PingFangSC-Regular;
            font-size: 28px;
            color: #FF2436;
            text-align: center;
            font-weight: 400;
            flex: 1;
            padding-right: 24px;
            justify-content: flex-end;

            span {
                font-size: 32px;
            }
        }

        .hxm-picker-title {
            flex: 3.2;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            justify-content: center;
            width: 60%;
            font-weight: 600;

            span {
                font-size: 36px;
            }
        }
    }

    .hxm-picker-panel {
        color: #323232;
        box-sizing: border-box;

        .hxm-picker-mask-top,
        .hxm-picker-mask-bottom {
            position: absolute;
            left: 0;
            right: 0;
            height: 160px;
            z-index: 1;
            pointer-events: none;
        }
    }

    .hxm-picker-wheel-wrapper {
        display: flex;
        padding: 0 24px;
        position: relative;

        .hxm-picker-wheel {
            flex: 1;
            height: 400px;
            overflow: hidden;
        }

        .hxm-picker-wheel-scroll {
            position: relative;
            top: 160px;

            .hxm-picker-wheel-item {
                height: 80px;
                display: flex;
                justify-content: center;
                align-items: center;

                * {
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }

                span {
                    font-size: 38px;
                }
            }
        }
    }
}

[theme-mode="black"] {

    #hxm-picker {
        .hxm-picker-container {
            background-color: #1e1e1e;
        }

        .hxm-picker-cancel {
            color: #999;
        }

        .hxm-picker-wheel {
            color: #d2d2d3;
        }

        .hxm-picker-mask-top {
            top: 0;
            border-bottom: 1px solid rgba(30, 30, 30, .9);
            background: linear-gradient(to bottom, rgba(30, 30, 30, .9), rgba(30, 30, 30, .5));
        }

        .hxm-picker-mask-bottom {
            bottom: 0;
            border-top: 1px solid rgba(30, 30, 30, .9);
            background: linear-gradient(to top, rgba(30, 30, 30, .9), rgba(30, 30, 30, .5));
        }
    }
}
</style>